#include "stdafx.h"
#include "BufferLayout.h"

namespace Reign
{namespace Video
{namespace D3D10
{
	#pragma region Properties
	D3D10_INPUT_ELEMENT_DESC* BufferLayoutDesc::Desc::get() {return desc;}
	#pragma endregion

	#pragma region Constructors
	BufferLayoutDesc::BufferLayoutDesc(List<BufferLayoutElement>^ elements)
	: BufferLayoutDescI(elements)
	{
		init();
	}

	BufferLayoutDesc::BufferLayoutDesc(BufferLayoutTypes bufferLayoutType)
	: BufferLayoutDescI(bufferLayoutType)
	{
		init();
	}

	void BufferLayoutDesc::init()
	{
		null();
		try
		{
			desc = new D3D10_INPUT_ELEMENT_DESC[ElementCount];
			uint i = 0;
			for each(BufferLayoutElement element in Elements)
			{
				switch (element.Usage)
				{
					case (BufferLayoutElementUsages::Position): desc[i].SemanticName = "POSITION"; break;
					case (BufferLayoutElementUsages::Color): desc[i].SemanticName = "COLOR"; break;
					case (BufferLayoutElementUsages::UV): desc[i].SemanticName = "TEXCOORD"; break;
					case (BufferLayoutElementUsages::Normal): desc[i].SemanticName = "NORMAL"; break;
					case (BufferLayoutElementUsages::Index): desc[i].SemanticName = "BLENDINDICES"; break;
					case (BufferLayoutElementUsages::IndexClassic): desc[i].SemanticName = "BLENDINDICES"; break;
				}

				switch (element.Type)
				{
					case (BufferLayoutElementTypes::Float): desc[i].Format = DXGI_FORMAT_R32_FLOAT; break;
					case (BufferLayoutElementTypes::Vector2): desc[i].Format = DXGI_FORMAT_R32G32_FLOAT; break;
					case (BufferLayoutElementTypes::Vector3): desc[i].Format = DXGI_FORMAT_R32G32B32_FLOAT; break;
					case (BufferLayoutElementTypes::Vector4): desc[i].Format = DXGI_FORMAT_R32G32B32A32_FLOAT; break;
					case (BufferLayoutElementTypes::RGBAx8): desc[i].Format = DXGI_FORMAT_R8G8B8A8_UNORM; break;
				}

				desc[i].SemanticIndex = element.UsageIndex;
				desc[i].InputSlot = element.StreamIndex;
				desc[i].AlignedByteOffset = element.ByteOffset;
				desc[i].InputSlotClass = element.StreamIndex == 0 ? D3D10_INPUT_PER_VERTEX_DATA : D3D10_INPUT_PER_INSTANCE_DATA;
				desc[i].InstanceDataStepRate = element.StreamIndex == 0 ? 0 : 1;
				++i;
			}
		}
		catch (Exception^ ex)
		{
			delete this;
			throw ex;
		}
	}

	BufferLayoutDesc::~BufferLayoutDesc()
	{
		if (desc) delete desc;
		null();
	}

	void BufferLayoutDesc::null()
	{
		desc = 0;
	}
	#pragma endregion
}
}
}